package com.kma.summer2012.dao;

import com.kma.summer2012.factory.DAOFactory;
import com.kma.summer2012.factory.HibernateUtil;
import com.kma.summer2012.factory.SpringBeansFactory;
import com.kma.summer2012.model.*;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;

import java.sql.SQLException;
import java.util.*;


public class CrumbsRequestDAOImpl implements CrumbsRequestDAO {

    @Override
    public int findClientIdByRequest(Integer requestID) {

        Session session = null;
        int result = -1;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            //SQLQuery query = session.createSQLQuery("SELECT CLIENT_ID FROM CRUMBS_REQUEST WHERE ID like ?").addEntity(CrumbsRequest.class);
            //  List pusList = query.setParameter(0,(int)requestID).list();
            //  SQLQuery qry = session.createSQLQuery("select CLIENT_ID from CRUMBS_REQUEST WHERE").addEntity(CrumbsRequest.class);
            // List l = qry.list();
            //   Query query = session.createQuery("FROM CRUMBS_REQUEST WHERE ID = :code");
            /* query.setParameter("code", requestID);
       List list = query.list();
       Iterator it = list.iterator();
       while (it.hasNext()) {
           result = (Integer) it.next();

       }     */

            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return result;
    }

    @Override
    public void add(CrumbsRequest request) {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(request);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    @Override
    public CrumbsRequest addRequest(CrumbsRequest request) throws SQLException {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(request);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return request;
    }

    @Override
    public CrumbsRequest initByAdditionalTools(int reqID) throws SQLException {
        Session session = null;
        CrumbsRequest request = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            request = (CrumbsRequest) session.get(CrumbsRequest.class, reqID);
            if (request != null) {
                Hibernate.initialize(request.getCrumbsAdditionalTools());
                for (CrumbsAdditionalTools tool : request.getCrumbsAdditionalTools()) {
                    Hibernate.initialize(tool.getCrumbsCatalogOfTools());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return request;
    }

    @Override
    public CrumbsRequest getByClientId(int clientID) throws SQLException {
        Session session = null;
        CrumbsRequest request = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            request = (CrumbsRequest) session.get(CrumbsRequest.class, clientID);
        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return request;
    }

    @Override
    public void update(CrumbsRequest request) {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.update(request);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }


    }

    @Override
    public CrumbsRequest getById(int request_id) {
        Session session = null;
        CrumbsRequest request = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            request = (CrumbsRequest) session.get(CrumbsRequest.class, request_id);
            if (request != null) {
                Hibernate.initialize(request.getCrumbsProcessHistories());
                Hibernate.initialize(request.getCrumbsUsers());
                Hibernate.initialize((request.getCrumbsRequestAndWorks()));
                if (request.getCrumbsUsers() != null) {
                    Hibernate.initialize(request.getCrumbsUsers());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return request;
    }

    @Override
    public Collection<CrumbsRequest> getAll() {
        Session session = null;
        List<CrumbsRequest> requests = new ArrayList<CrumbsRequest>();
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            requests = session.createCriteria(CrumbsRequest.class).list();
            for (CrumbsRequest request : requests) {
                Hibernate.initialize(request.getCrumbsProcessHistories());
                Hibernate.initialize(request.getCrumbsRequestAndWorks());
                if (request.getCrumbsUsers() != null) {
                    Hibernate.initialize(request.getCrumbsUsers());
                }
                for (CrumbsRequestAndWork work : request.getCrumbsRequestAndWorks()) {
                    if (work.getCrumbsCatalogOfWork() != null) {
                        Hibernate.initialize(work.getCrumbsCatalogOfWork());
                        Set<CrumbsCatalogOfTools> tools = work.getCrumbsCatalogOfWork().getCrumbsCatalogOfTools();
                        for (CrumbsCatalogOfTools tool : tools) {
                            Hibernate.initialize(tool);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return requests;
    }

    @Override
    public void delete(CrumbsRequest request) {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.delete(request);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    public List<CrumbsRequest> getAllForUser(CrumbsUser user) throws SQLException {
        if (user == null) return null;
        DAOFactory factory = SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        Disjunction disjunction = Restrictions.disjunction();
        if (user.getCrumbsPosition().getName().equals("Manager")) {
            disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(2)));
            disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(4)));
        } else if (user.getCrumbsPosition().getName().equals("Engineer")) {
            disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(3)));
        } else if (user.getCrumbsPosition().getName().equals("Operator")) {
            disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(1)));
            disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(5)));
        }

        List<CrumbsRequest> requests = null;
        List<CrumbsRequest> result = new ArrayList<CrumbsRequest>();
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            requests = session.createCriteria(CrumbsRequest.class).add(disjunction).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
            for (CrumbsRequest request : requests) {
                if (user.getCrumbsPosition().getName().equals("Manager")) {
                    result.add(request);
                } else {
                    Hibernate.initialize(request.getCrumbsProcessHistories());
                    if (request.getCrumbsUsers() != null) {
                        Hibernate.initialize(request.getCrumbsUsers());
                    }
                    Boolean validate = false;
                    Set<CrumbsProcessHistory> history = request.getCrumbsProcessHistories();
                    ArrayList<CrumbsProcessHistory> historyArrayList = new ArrayList<CrumbsProcessHistory>();
                    historyArrayList.addAll(history);
                    Collections.sort(historyArrayList, new Comparator<CrumbsProcessHistory>() {
                        @Override
                        public int compare(CrumbsProcessHistory o1, CrumbsProcessHistory o2) {
                            return o1.getId() - o2.getId();
                        }
                    });
                    if (historyArrayList.size() > 0) {
                        CrumbsProcessHistory lastItem = historyArrayList.get(historyArrayList.size() - 1);
                        if (lastItem.getCrumbsUserByRecieverId().getUserId() == user.getUserId()) {
                            result.add(request);
                        } else {
                            continue;
                        }
                    }
                }

                Hibernate.initialize(request.getCrumbsRequestAndWorks());
                Hibernate.initialize(request.getCrumbsProcessHistories());
                for (CrumbsRequestAndWork work : request.getCrumbsRequestAndWorks()) {
                    if (work.getCrumbsCatalogOfWork() != null) {
                        Hibernate.initialize(work.getCrumbsCatalogOfWork());
                        Set<CrumbsCatalogOfTools> tools = work.getCrumbsCatalogOfWork().getCrumbsCatalogOfTools();
                        for (CrumbsCatalogOfTools tool : tools) {
                            Hibernate.initialize(tool);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return result;
    }

    @Override
    public List<CrumbsRequest> getAllClosed() throws SQLException {
        DAOFactory factory = SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(Restrictions.eq("crumbsRequestsState", factory.getCrumbsRequestsStateDAO().getById(6)));

        List<CrumbsRequest> requests = null;
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            requests = session.createCriteria(CrumbsRequest.class).add(disjunction).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
            for (CrumbsRequest request : requests) {
                Hibernate.initialize(request.getCrumbsRequestAndWorks());
                Hibernate.initialize(request.getCrumbsProcessHistories());
                for (CrumbsRequestAndWork work : request.getCrumbsRequestAndWorks()) {
                    if (work.getCrumbsCatalogOfWork() != null) {
                        Hibernate.initialize(work.getCrumbsCatalogOfWork());
                        Set<CrumbsCatalogOfTools> tools = work.getCrumbsCatalogOfWork().getCrumbsCatalogOfTools();
                        for (CrumbsCatalogOfTools tool : tools) {
                            Hibernate.initialize(tool);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return requests;
    }

    @Override
    public void deleteAll(List<CrumbsRequest> requests) {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            for (CrumbsRequest request : requests)
                session.delete(request);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }
}


